package com.ruoyi.business.listener;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ruoyi.business.domain.GoodsInfo;
import com.ruoyi.business.service.IGoodsInfoService;
import com.ruoyi.business.utils.MoneyValidator;
import com.ruoyi.business.utils.MyException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author ty
 */
@Slf4j
public class GoodsInfoExcelListener extends AnalysisEventListener<Map<Integer, String>> {

    @Autowired
    IGoodsInfoService goodsInfoService;

    public List<String> errorList = new ArrayList<>();
    private final List<GoodsInfo> saveList = new ArrayList<>();

    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");

    BigDecimal defaultValue = BigDecimal.ZERO;
    Long defaultLongValue = 0L;

    public GoodsInfoExcelListener(IGoodsInfoService goodsInfoService) {
        this.goodsInfoService = goodsInfoService;
    }

    @Override
    public void invoke(Map<Integer, String> data, AnalysisContext context) {
        int currentRowNum = context.readRowHolder().getRowIndex() + 1;
        log.info("第{}行解析数据: {}", currentRowNum, JSONUtil.toJsonStr(data));
        try {
            saveList.add(parseRowToGoodsInfo(data, currentRowNum));
        } catch (Exception e) {
            log.error("第{}行解析异常：{}", currentRowNum, e.getMessage(), e);
            errorList.add(String.format("第%s行错误：%s", currentRowNum, e.getMessage()));
        }
    }


    private GoodsInfo parseRowToGoodsInfo(Map<Integer, String> data, int rowNum) throws Exception {
        List<String> list = new ArrayList<>();
        for (int i = 0; i <= 20; i++) {
            String val = data.get(i);
            list.add(val != null ? val.trim() : "");
        }

        GoodsInfo info = new GoodsInfo();
        info.setRowNum(rowNum);
        //商品id
        String goodsId = list.get(0);
        //商品名称
        String title = list.get(1);
        //规格名称
        String specValueName = list.get(2);
        //规格编码
        String outerSkuCode = list.get(3);
        //规格条码
        String skuBarCode = list.get(4);
        //商品销售价格
        String salePrice = StrUtil.blankToDefault(list.get(5), null);
        //商品数量
        String skuNum = list.get(6);
        String skuId = list.get(7);
        //类目
        String categoryName = list.get(8);
        //备注
        String remark = list.get(9);
        if (StrUtil.isBlank(goodsId) && StrUtil.isBlank(skuBarCode)) {
            throw new MyException("不能都为空，导入数据无效,至少需要提供商品id或规格条码");
        }
        info.setGoodsId(convertToLong(goodsId, defaultLongValue));
        info.setTitle(StrUtil.blankToDefault(title, ""));
        info.setSpecValueName(StrUtil.blankToDefault(specValueName, ""));
        info.setSkuCode(StrUtil.blankToDefault(outerSkuCode, ""));
        info.setSkuBarCode(StrUtil.blankToDefault(skuBarCode, ""));
        BigDecimal validatorSalePrice = MoneyValidator.parseMoney(salePrice);
        info.setSalePrice(validatorSalePrice);
        info.setSkuNum(convertToLong(skuNum, null));
        info.setSkuId(convertToLong(skuId, defaultLongValue));
        info.setCreateTime(DateUtils.getNowDate());
        info.setRemark(remark);
        if (StringUtils.isEmpty(categoryName)) {
            throw new MyException("商品类目为空,请选择商品类目");
        }
        info.setCategoryId(Long.parseLong(DictUtils.getDictValue("sys_goods_category", categoryName)));
        return info;
    }


    public static BigDecimal convertToBigDecimal(String value, BigDecimal defaultValue) {
        return Convert.toBigDecimal(value, defaultValue);
    }

    public static Long convertToLong(String value, Long defaultValue) {
        return Convert.toLong(value, defaultValue);
    }

    private Date parseDate(String dateStr) throws ParseException {
        return StrUtil.isNotBlank(dateStr) ? new Timestamp(SDF.parse(dateStr).getTime()) : null;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (CollUtil.isEmpty(saveList)) {
            return;
        }
        if (CollUtil.isNotEmpty(errorList)) {
            return;
        }
        try {
            log.info("共{}条数据，开始入库", saveList.size());
            goodsInfoService.batchInsertOrUpdateByImport(saveList);
            log.info("入库成功！");
        } catch (Exception e) {
            log.error("数据入库异常：{}", e.getMessage(), e);
            errorList.add("数据入库异常：" + e.getMessage());
        }
    }

}
